﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.Administration;
using Microsoft.Office.Server.Search.Administration;
using System.Data;
using SPThumbnailExtender.Interne;
using Microsoft.SharePoint;
using Microsoft.Office.Server.Search.Query;
using System.IO;
using Microsoft.SharePoint.Utilities;
using System.Web;

namespace SPThumbnailExtender
{
    public class ThumbnailExtenderTimerJob : SPJobDefinition
    {
        public static string JobName = "ThumbnailExtenderTimerJob";

        public ThumbnailExtenderTimerJob()
            : base()
        { }
        public ThumbnailExtenderTimerJob(SPWebApplication webApplication)
            : base(JobName, webApplication, null, SPJobLockType.ContentDatabase)
        {
            this.Title = JobName;
        }

        public override void Execute(Guid targetInstanceId)
        {
            try
            {
                string ssaName = Helper.GetParameter("SPThumbnailExtender.ServiceApplication").ToString();
                string ContentSourceValue = Helper.GetParameter("SPThumbnailExtender.ContentSource").ToString();
                SearchQueryAndSiteSettingsServiceProxy settingsProxy = SPFarm.Local.ServiceProxies.GetValue<SearchQueryAndSiteSettingsServiceProxy>();
                SearchServiceApplicationProxy searchApplicationProxy = settingsProxy.ApplicationProxies.GetValue<SearchServiceApplicationProxy>(ssaName);
                using (KeywordQuery keywordQuery = new KeywordQuery(searchApplicationProxy))
                {

                    keywordQuery.QueryText = "IsDocument=\"true\"  ContentSource=\"" + ContentSourceValue + "\"";
                    keywordQuery.TrimDuplicates = false;
                    keywordQuery.RowLimit = 50;
                    int totalRow = -1;
                    int iCurrentRow = 0;
                    do
                    {
                        try
                        {
                            keywordQuery.StartRow = iCurrentRow;
                            if (searchApplicationProxy.FASTAdminProxy != null)
                            {
                                keywordQuery.ResultTypes = ResultType.RelevantResults | ResultType.SpecialTermResults;
                                keywordQuery.ResultsProvider = SearchProvider.FASTSearch;
                            }
                            else
                            {
                                keywordQuery.ResultTypes = ResultType.RelevantResults;
                                keywordQuery.ResultsProvider = SearchProvider.SharepointSearch;
                            }

                            ResultTableCollection resultsTableCollection = keywordQuery.Execute();


                            ResultTable searchResultsTableRelevantResults = resultsTableCollection[ResultType.RelevantResults];
                            if (totalRow == -1)
                                if(searchApplicationProxy.FASTAdminProxy!=null)
                                    totalRow = searchResultsTableRelevantResults.TotalRowsIncludingDuplicates;
                                else
                                    totalRow = searchResultsTableRelevantResults.TotalRows;
                            DataTable resultsDataTableRelevantResults = new DataTable();
                            resultsDataTableRelevantResults.TableName = "RelevantResults";
                            resultsDataTableRelevantResults.Load(searchResultsTableRelevantResults, LoadOption.OverwriteChanges);
                            int nbTotal = resultsDataTableRelevantResults.Rows.Count;
                            string FieldUrl="";
                            if (resultsDataTableRelevantResults.Columns.Contains("Url"))
                                FieldUrl = "Url";
                            else 
                                FieldUrl = "Path";
                            
                            foreach (DataRow dr in resultsDataTableRelevantResults.Rows)
                            {
                                ProcessRow(dr,FieldUrl);
                                iCurrentRow++;
                            }
                            int iPercent = (iCurrentRow * 100 / totalRow);

                            this.UpdateProgress(iPercent);
                        }
                        catch (Exception ex)
                        {
                            LogManager.LogInfo(ex);
                        }
                    } while (iCurrentRow < totalRow);

                }
            }
            catch (Exception ex)
            {
                LogManager.LogInfo(ex);
            }


            base.Execute(targetInstanceId);
        }

        private void ProcessRow(DataRow dr, string FieldUrl)
        {            
            string strUrl = dr[FieldUrl] as string;
            
            Uri uriUrl = new Uri(strUrl, UriKind.Absolute);
            if (!Helper.IsFileExist(uriUrl))
                return;
            //DateTime? dtWrite = Helper.GetDateTime(uriUrl, dr["Write"].ToString());

            DateTime dtWrite;
            if(dr["Write"].ToString().Contains('Z'))
                dtWrite = SPUtility.CreateDateTimeFromISO8601DateTimeString(dr["Write"].ToString());
            else
                dtWrite = Helper.GetDateTime(uriUrl, dr["Write"].ToString());
            
                foreach (SPAlternateUrl au in this.WebApplication.AlternateUrls)
                {
                    if (strUrl.StartsWith(au.IncomingUrl))
                    {
                        strUrl = strUrl.Replace(au.Uri.AbsoluteUri, this.WebApplication.GetResponseUri(SPUrlZone.Default).AbsoluteUri);
                    }
                }
                if (strUrl != string.Empty )
                    ProcessFile(strUrl,dtWrite);
        }

        private void ProcessFile(string strUrl, DateTime dtWrite)
        {
            LogManager.LogInfo(strUrl);
            Uri uri = new Uri(strUrl, UriKind.Absolute);

            if (uri.Scheme.ToLower().StartsWith("http"))
            {
                try
                {
                    DateTime? TimeInsert = Helper.GetDocumentDate(uri);

                    //DateTime TimeUpdate = Helper.GetDateTimeFile(uri);
                    if (TimeInsert.HasValue && TimeInsert > dtWrite)
                        return;
                    ThumbnailBase factory = ThumbnailFactory.GenerateThumbnail(uri);
                    if (factory == null)
                        return;
                    factory.GenerateThumbnails();
                }
                catch (Exception ex)
                {
                    LogManager.LogInfo(ex);
                }
            }

        }

    }
}
